package com.kang.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kang.base.LoginDataBase;
import com.kang.entity.SysUser;
import com.kang.mapper.LoginMapper;
import com.kang.service.LoginService;
import com.kang.util.*;
import com.kang.vo.CaptchaLoginVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class LoginServiceImpl extends ServiceImpl<LoginMapper, SysUser> implements LoginService {

    @Autowired
    private LoginMapper loginMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Map<String, Object> informationLogin(SysUser sysUser) throws Exception {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("phone",AESSimpleUtil.encrypt(sysUser.getPhone())).eq("password", AESSimpleUtil.encrypt(sysUser.getPassword()))
                .eq("type",2);
        SysUser user = loginMapper.selectOne(wrapper);
        if (Objects.isNull(user)) {
            throw new Exception("手机号密码错误");
        }
        if (user.getStatus() == 0) {
            throw new Exception("当前账号被禁用");
        }
        //用户信息存入token中
        String subject = user.getId() + "-" + user.getUsername();
        String token = JwtUtil.createJWT(subject);
        LoginDataBase loginDataBase = new LoginDataBase();
        loginDataBase.setUser(user);
        stringRedisTemplate.opsForValue().set("login:token:" + token, JSONObject.toJSONString(loginDataBase),30, TimeUnit.MINUTES);
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("token",token);
        resultMap.put("id",user.getId());
        resultMap.put("headUrl",user.getHeadUrl());

        //统计登录用户量   年月日做key
        LocalDateTime localDateTime = LocalDateTime.now();
        String format = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        stringRedisTemplate.opsForValue().setBit("userCount:" + format,user.getId(),true);
        return resultMap;
    }

    @Override
    public Map<String,Object> phoneLogin(CaptchaLoginVo captchaLoginVo) throws Exception {
        Map<String,Object> resultMap = new HashMap<>();
        String capR = stringRedisTemplate.opsForValue().get("login:phone:" + captchaLoginVo.getPhoneNumber());
        // 判断验证码是否正确
        assert capR != null;
        if (!capR.equals(captchaLoginVo.getCaptcha())) {
            throw new Exception("验证码错误");
        }
        //判断是否注册
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("phone", AESSimpleUtil.encrypt(captchaLoginVo.getPhoneNumber())).eq("type", 2).eq("status",1);
        SysUser sysUser = loginMapper.selectOne(wrapper);
        String token = null;
        LoginDataBase loginDataBase = new LoginDataBase();
        //统计登录用户量   年月日做key
        LocalDateTime localDateTime = LocalDateTime.now();
        String format = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        if (Objects.isNull(sysUser)) {
            SysUser user = new SysUser();
            user.setUsername("游客");
            user.setPassword("965eb72c92a549dd");  //密码固定111111
            user.setName("游客");
            user.setPhone(AESSimpleUtil.encrypt(captchaLoginVo.getPhoneNumber()));
            user.setHeadUrl("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
            user.setStatus(1);
            user.setType(2);
            user.setIsDeleted(0);
            user.setCreateTime(new Date());
            user.setUpdateTime(new Date());
            user.setAge(18);
            user.setSex(1);
            loginMapper.insert(user);
            stringRedisTemplate.opsForValue().setBit("userCount:" + format,user.getId(),true);
            resultMap.put("id",user.getId());
            resultMap.put("headUrl",user.getHeadUrl());
            //用户信息存入token中
            String subject = user.getId() + "-" + user.getUsername();
            token = JwtUtil.createJWT(subject);
            loginDataBase.setUser(user);
            stringRedisTemplate.opsForValue().set("login:token:" + token, JSONObject.toJSONString(loginDataBase),30, TimeUnit.MINUTES);
        } else {
            stringRedisTemplate.opsForValue().setBit("userCount:" + format,sysUser.getId(),true);
            //用户信息存入token中
            String subject = sysUser.getId() + "-" + sysUser.getUsername();
            token = JwtUtil.createJWT(subject);
            loginDataBase.setUser(sysUser);
            stringRedisTemplate.opsForValue().set("login:token:" + token, JSONObject.toJSONString(loginDataBase),30, TimeUnit.MINUTES);
            resultMap.put("id",sysUser.getId());
            resultMap.put("headUrl",sysUser.getHeadUrl());
        }
        resultMap.put("token",token);
        return resultMap;
    }

    @Override
    public String sendSms(CaptchaLoginVo captchaLoginVo) {
        String cap = SendSms.sendMessage(captchaLoginVo.getPhoneNumber());
        stringRedisTemplate.opsForValue().set("login:phone:" + captchaLoginVo.getPhoneNumber(),cap,90,TimeUnit.SECONDS);
        return null;
    }

    @Override
    public boolean findPass(CaptchaLoginVo captchaLoginVo) throws Exception {
        //拿到验证码进行比较是否正确
        String capt = stringRedisTemplate.opsForValue().get("login:phone:" + captchaLoginVo.getPhoneNumber());
        if (capt == null || !capt.equals(captchaLoginVo.getCaptcha())) {
            throw new Exception("验证码有误");
        }
        //修改密码
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("phone", AESSimpleUtil.encrypt(captchaLoginVo.getPhoneNumber()));
        updateWrapper.set("password", AESSimpleUtil.encrypt(captchaLoginVo.getPassword()));
        baseMapper.update(null, updateWrapper);
        return true;
    }

    @Override
    public Boolean layout(String token) {
        String rep = JSON.parseObject(token).get("token").toString();
        return stringRedisTemplate.delete("login:token:" + rep);
    }
}
